package com.woniuxy.life.filesystem.controller;

import com.woniuxy.life.core.api.CommonResult;
import com.woniuxy.life.filesystem.dto.MinioUploadDto;
import io.minio.MinioClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

@Api(tags = "MinioController", description = "MinIO对象存储管理")
@RestController
@RequestMapping("/minio")
@Slf4j
public class MinioController {

    @Value("${minio.endpoint}")
    private String endpoint;
    @Value("${minio.bucketName}")
    private String bucketName;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;

    @ApiOperation("文件上传")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public CommonResult upload(@RequestParam("file") MultipartFile file) {
        try {
            //创建一个MinIO的Java客户端
            MinioClient minioClient = new MinioClient(endpoint, accessKey, secretKey);
            boolean isExist = minioClient.bucketExists(bucketName);
            if (!isExist) {
                //创建存储桶
                minioClient.makeBucket(bucketName);
            }
            //获取上传文件的名称
            String filename = file.getOriginalFilename();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 设置存储对象名称
            String objectName = sdf.format(new Date()) + "/" + filename;
            // 使用putObject上传一个文件到存储桶中
            minioClient.putObject(bucketName, objectName, file.getInputStream(), file.getContentType());
            log.info("文件上传成功!");
            MinioUploadDto minioUploadDto = new MinioUploadDto();
            minioUploadDto.setName(filename);
            minioUploadDto.setUrl(endpoint + "/" + bucketName + "/" + objectName);
            return CommonResult.success(minioUploadDto);
        } catch (Exception e) {
            log.info("上传发生错误: {}！", e.getMessage());
        }
        return CommonResult.failed("文件上传失败");
    }

    @ApiOperation("文件删除")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public CommonResult delete(@RequestParam("objectName") String objectName) {
        try {
            MinioClient minioClient = new MinioClient(endpoint, accessKey, secretKey);
            minioClient.removeObject(bucketName, objectName);
            return CommonResult.success(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.failed("文件删除失败");
    }

    @ApiOperation("文件下载")
    @GetMapping("/download")
    public ResponseEntity download(@RequestParam("filename") String filename) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse httpResponse = servletRequestAttributes.getResponse();
        ResponseEntity entity = null;
        try {
            MinioClient minioClient = new MinioClient(endpoint, accessKey, secretKey);
            InputStream inputStream = minioClient.getObject(bucketName, filename);
            HttpHeaders headers = new HttpHeaders();
            //以附件的形式传输
            headers.setContentDispositionFormData("attachment;",filename);
            //inputStream.available() 获取从字节流中获取读取文件字节大小
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            entity = new ResponseEntity(buffer, headers, HttpStatus.OK);
        } catch (Exception ex) {
            log.info("导出失败：", ex.getMessage());
            entity = new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return entity;
    }
}
